import 'dart:convert';
import 'dart:math';

import 'package:audioplayers/audioplayers.dart';
import 'package:music_player/bean/music_bean.dart';
import 'package:music_player/enums/music_mode.dart';
import 'package:music_player/http/api.dart';
import 'package:music_player/widget/MusicCore.dart';
import 'package:music_player/widget/toast.dart';
import 'package:flutter/widgets.dart';

class MusicModel extends ChangeNotifier{

  // 当前音乐是否在播放
  bool play = false;

  String url = "";
  // 当前播放的音乐索引
  int playIndex = 0;

  // 音乐列表
  List<MusicBean> _musicList  = [
  MusicBean("天下",showLrc: false, playUrl: Api.MUSIC_URL, imageUrl: Api.IMAGE_URL),
  MusicBean("不愿回头",showLrc: false, playUrl: Api.MUSIC_URL2, imageUrl: "D:/图片/Snipaste_2024-07-20_21-01-54.png"),
  MusicBean("鸳鸯戏",showLrc: false, playUrl: "D:/迅雷下载/鸳鸯戏.mp3", imageUrl: "D:/图片/Snipaste_2024-07-20_21-01-54.png"),
  MusicBean("Stay",showLrc: false, playUrl: "D:/迅雷下载/stay.mp3", imageUrl: "D:/图片/Snipaste_2024-07-20_21-01-54.png"),
  ];

  List<MusicBean> get musicList => _musicList;
  set musicList(value){
    _musicList = value;
    thisMusic = musicList.first;
  }

  // 当前播放的音乐信息
  MusicBean thisMusic =  MusicBean("时间都去哪儿了",showLrc: false, playUrl: Api.MUSIC_URL, imageUrl: Api.IMAGE_URL);

  MusicModel(){
    thisMusic = musicList.first;
  }

  // 音乐播放模式 （单曲循环，顺序播放，随机播放）
  MusicMode _musicMode = MusicMode.sequentialPlay;
  MusicMode get musicMode => _musicMode;
  set musicMode(MusicMode value){
    _musicMode = value;
    notifyListeners();
  }

  // 音乐歌词列表
  final List<Word> _lrcList = [];
  List<Word> get lrcList => _lrcList;

  // 歌词列表控制器
  final ScrollController scrollController = ScrollController();

  // 音乐播放器
  final AudioPlayer _player = AudioPlayer();

  // 音乐播放的时长
  double _musicLength = 100.0;
  double get musicLength =>_musicLength;
  set musicLength(value){
    _musicLength = value;
    notifyListeners();
  }
  // 当前播放的时长
  double _playLength = 0.0;
  double get playLength => _playLength;
  set playLength(value){
    _playLength = value;
    // scrollController.animateTo(scrollController.position.maxScrollExtent/musicLength *value, duration: Duration(seconds: 1), curve: Curves.linear);
    if(thisMusic.showLrc) {
      scrollController.jumpTo(
          scrollController.position.maxScrollExtent / musicLength * value);
    }

    notifyListeners();
  }

  // 是否在拖动进度条
  bool isSliver = false;

  // 音乐是否播放完毕
  bool _playComplete = false;

  // 当前播放器音量
  double get volume => _player.volume;
  set volume(value) {
    _player.setVolume(value);
    notifyListeners();
  }

  // 获取歌词并设置
  void lrc() async{
    List<String> list = [];

    try {
      // 数据处理
      final res = await Api.getLyric(thisMusic.lrcUrl);
      final json = jsonDecode(res.toString());
      final lrc = json["lrc"]["lyric"].toString();
      list = lrc.split("\n");
    } catch (e) {
      debugPrint("歌词获取失败,$e");
      thisMusic.showLrc = false;
      return;
    }

    // 清空歌词列表
    _lrcList.clear();

    // 添加歌词标题
    _lrcList.add(Word(thisMusic.title,title: true));
    // 添加歌词
    for (var s in list) {
      if(s.isNotEmpty){
        _lrcList.add(Word(s));
      }
    }
    notifyListeners();
  }


  // 设置播放进度
  void seekMusic(double value) async{
    _player.seek(Duration(milliseconds: value.toInt()));
  }

  // 播放失败，尝试播放的次数
  int _tryPlayCount = 0;

  // 播放音乐
  void playMusic(BuildContext context) async{
    if(!play){
      Source source = thisMusic.playUrl.endsWith("http")
          ?UrlSource(thisMusic.playUrl):
          DeviceFileSource(thisMusic.playUrl);
      // 播放并初始化
      _player.play(source)
      .then((value) => musicListen(context))
          .catchError((err){
            // 播放异常，释放当前缓冲
        debugPrint("播放出错：$err");
        Toast.show(context, "播放出错");
         _player.release();
         play = false;
        notifyListeners();
        // 当前歌曲播放出错播放下一首,尝试播放列表的最大次数
        if(_tryPlayCount < musicList.length) {
          nextMusic(context);
          _tryPlayCount++;
        }else{
          _tryPlayCount = 0;
        }

      });
    }else{
      _player.pause();
    }
    play = !play;
    // 是否显示歌词
    if(thisMusic.showLrc) lrc();
    notifyListeners();
  }

  // 音乐事件监听
  void musicListen(context) async{
    final len = await _player.getDuration();
    musicLength =len?.inMilliseconds.toDouble()??0.0;

    // 监听音乐时长变化
    _player.onPositionChanged.listen((Duration duration) {
      _playComplete = false;
      // 如果在拖动就不更新
      if(!isSliver) {
        // 单位转化为毫秒
        playLength = duration.inMilliseconds.toDouble();
      }
    });

    // 音乐播放完成回调
    _player.onPlayerComplete.listen((event) {
      if (!_playComplete) {
        debugPrint("音乐播放完毕：");

        switch (musicMode) {
          case MusicMode.singleLoop:
            changeMusic(context);
            break;
          case MusicMode.randomPlay:
            int next = Random.secure().nextInt(musicList.length);
            debugPrint("next:$next");
            thisMusic = musicList[next];
            changeMusic(context);
            break;
          case MusicMode.sequentialPlay:
            nextMusic(context);
            break;
          default:
            nextMusic(context);
            break;
        }
      }
      _playComplete = true;
    });
  }

  // 改变播放源
  void changeMusic(context) async{
    await _player.release();
    play = false;
    playMusic(context);
  }

  // 返回下一首音乐
  MusicBean nextMusic(context){
    _changePlayIndex(true);
    thisMusic = musicList[playIndex];
    changeMusic(context);
    notifyListeners();
    return musicList[playIndex];
  }

  // 返回上一首音乐
  MusicBean previousMusic(context){
    _changePlayIndex(false);
    thisMusic = musicList[playIndex];
    changeMusic(context);
    notifyListeners();
    return musicList[playIndex];
  }

  // 统一安全处理
  void _changePlayIndex(bool it){
    // 安全处理
    if(it) {
      if (playIndex >= musicList.length - 1) {
        playIndex = 0;
        print("操作异常1");
        return;
      }
    }else {
      if (playIndex <= 0) {
        playIndex = musicList.length - 1;
        print("操作异常2");
        return;
      }
    }

    if(it) {
      playIndex++;
    } else{
      playIndex--;
    }

  }

}